package com.serkol.ams.controller.api;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.util.DateUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.serkol.ams.bean.MyPageOld;
import com.serkol.ams.bean.Result;
import com.serkol.ams.entity.*;
import com.serkol.ams.service.*;
import com.serkol.annotation.IsLogin;
import com.serkol.component.SystemSettingUtils;
import com.serkol.constant.AuthConstant;
import com.serkol.exception.AuthException;
import com.serkol.utils.OrderUtils;
import com.serkol.wx.bean.WithdrawalAppervalMsg;
import com.serkol.wx.service.WechatMpMessageService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.function.Function;

@RestController
@RequestMapping("api/users/wallet")
public class UsersWalletApiController {
    @Autowired
    private WechatMpMessageService wechatMpMessageService;
    @Value("${upload.path}")
    private String uploadpath;
    @Value("${upload.host}")
    private String uploadhost;
    @Autowired
    private UsersService userService;
    @Autowired
    private UsersWalletService walletService;

    @Autowired
    private UsersWalletLogService walletLogService;
    @Autowired
    private UsersWalletIntegralLogService walletIntegralLogService;

    @Autowired
    private UsersSignLogService signLogService;

    @Autowired
    private SystemSettingUtils systemSettingUtils;
    @Autowired
    private UsersWalletWithdrawalService walletWithdrawalService;

    @Autowired
    private UsersAuthenticationService usersAuthenticationService;

    @Autowired
    private NotifyService notifyService;


    @Autowired
    private UsersWalletTransferService usersWalletTransferService;


    @Autowired
    private WxMaService wxMaService;

    @IsLogin
    @GetMapping("/getInfo")
    @ResponseBody
    public Result getInfo() {
        String systemtaxespersent = systemSettingUtils.getInfo("systemtaxespersent");
        String systemservicefee = systemSettingUtils.getInfo("systemservicefee");
        double fee = Double.parseDouble(systemservicefee);
        double persent = Double.parseDouble(systemtaxespersent);
        Map<String, Object> info = walletService.getInfo();
        info.put("taxes", persent);
        info.put("servisefee", fee);
        return Result.ok(info);
    }

    @IsLogin
    @GetMapping("/getInfoLog")
    @ResponseBody
    public Result getInfoLog() {

        Map<String, Object> info = walletService.getInfoLog();

        return Result.ok(info);
    }

    @IsLogin
    @GetMapping("/getIncomeAndExpenses")
    @ResponseBody
    public Result getIncomeAndExpenses() {
        Map<String, Object> info = walletService.getIncomeAndExpenses();
        return Result.ok(info);
    }

    @IsLogin
    @GetMapping("/findByMyList")
    @ResponseBody
    public Result findByMyList(@RequestParam(name = "pageSize", defaultValue = "10") int pageSize, @RequestParam(name = "pageSize", defaultValue = "0") int current, @RequestParam(name = "state", defaultValue = "0") int state) {
     return  walletLogService.findByMyList(pageSize, current, state);

    }

    @IsLogin
    @GetMapping("/findByMyMiniList")
    @ResponseBody
    public Result findByMyMiniList(@RequestParam(name = "state", defaultValue = "0") int state, @RequestParam(name = "current", defaultValue = "0") int current) {
        List<UsersWalletLog> info = walletLogService.findByMyMiniList(state, current);
        return Result.ok(info);
    }

    @IsLogin
    @GetMapping("/findByBackLogList")
    @ResponseBody
    public Result findByBackLogList(@RequestParam(name = "pageSize", defaultValue = "10") int pageSize, @RequestParam(name = "current", defaultValue = "0") int current, @RequestParam(name = "state", defaultValue = "0") int state, @RequestParam(name = "userId", defaultValue = "0") long userId) {
        if (userId > 0) {
            return walletLogService.findByBackLogList(pageSize,current, state, userId);
        } else {
            return Result.failure();
        }
    }

    @IsLogin
    @GetMapping("/findByPageList")
    @ResponseBody
    public Result findByPageList(@RequestParam(name = "pageSize", defaultValue = "10") int pageSize, @RequestParam(name = "current", defaultValue = "0") int current,
                                 @RequestParam(name = "name", defaultValue = "") String name,
                                 @RequestParam(name = "phone", defaultValue = "") String phone,
                                 @RequestParam(name = "parentName", defaultValue = "") String parentName,
                                 @RequestParam(name = "balanceSort", defaultValue = "") String balanceSort,
                                 @RequestParam(name = "agentId", defaultValue = "0") long agentId) {

//        name: 18139134211
//        phone: 18139134211
//        parentName: 18139134211
//        agentId: 3
     return   walletService.findByPageList(pageSize,current, name, phone, parentName, agentId, balanceSort);


    }

    @IsLogin
    @GetMapping("/findByPageWithdrawalList")
    @ResponseBody
    public Result findByPageWithdrawalList(@RequestParam(name = "pageSize", defaultValue = "10") int pageSize, @RequestParam(name = "current", defaultValue = "0") int current, @RequestParam(name = "status", defaultValue = "0") int status,
                                           @RequestParam(name = "authName", defaultValue = "") String authName) {

return walletWithdrawalService.findByPageList(pageSize,current, status, authName);

    }

    @IsLogin
    @GetMapping("/findByPageWithdrawalMiniList")
    @ResponseBody
    public Result findByPageWithdrawalMiniList(@RequestParam(name = "pageSize", defaultValue = "10") int pageSize, @RequestParam(name = "current", defaultValue = "0") int current, @RequestParam(name = "status", defaultValue = "0") int status,
                                               @RequestParam(name = "authName", defaultValue = "") String authName) {

   return walletWithdrawalService.findByPageList(pageSize,current, status, authName);
       // return Result.ok(info.getList());

    }

    @IsLogin
    @GetMapping("/findByPageLogList")
    @ResponseBody
    public Result findByPageLogList(@RequestParam(name = "pageSize", defaultValue = "10") int pageSize, @RequestParam(name = "current", defaultValue = "0") int current, @RequestParam(name = "state", defaultValue = "0") int state, @RequestParam(name = "type", defaultValue = "0") int type, @RequestParam(name = "name", defaultValue = "") String name, @RequestParam(name = "userId", defaultValue = "0") long userId) {

      return walletLogService.findByPageLogList(pageSize,current, state, name, type,userId);


    }

    @IsLogin
    @GetMapping("/findByBackIntegralLogList")
    @ResponseBody
    public Result findByBackIntegralLogList(@RequestParam(name = "pageSize", defaultValue = "10") int pageSize, @RequestParam(name = "current", defaultValue = "0") int current, @RequestParam(name = "state", defaultValue = "0") int state, @RequestParam(name = "userId", defaultValue = "0") long userId) {
        if (userId > 0) {
           return  walletIntegralLogService.findByBackLogList(pageSize,current, state, userId);

        } else {
            return Result.failure();
        }
    }

    @IsLogin
    @GetMapping("/findByMyWithdrawal")
    @ResponseBody
    public Result findByMyWithdrawal(@RequestParam(name = "pageSize", defaultValue = "10") int pageSize, @RequestParam(name = "pageSize", defaultValue = "0") int current, @RequestParam(name = "status", defaultValue = "0") int status) {
        MyPageOld info = walletWithdrawalService.findByMyWithdrawal(pageSize, current, status);
        return Result.ok(info);
    }

    @IsLogin
    @PostMapping("/withdrawal")
    @ResponseBody
    public Result getWithdrawal(@RequestBody UsersWalletWithdrawal data) {
        System.out.println(data);
        LoginLog loginLog = AuthConstant.getLoginLog();
        data.setOperatorId(loginLog.getUserId());
        data.setUpdateDate(new Date());
        long byWaitByUserCount = walletWithdrawalService.findByWaitByUserCount(loginLog.getUserId());
        if (byWaitByUserCount == 0) {
            String systemtaxespersent = systemSettingUtils.getInfo("systemtaxespersent");
            String systemservicefee = systemSettingUtils.getInfo("systemservicefee");
            data.setSn(OrderUtils.getOrderNum(loginLog.getUserId()));
            data.setUserId(loginLog.getUserId());
            if (data.getAmount().doubleValue() > 0) {
                data.setRemark(data.getName() + "پۇل چۈشۈردى");
                UsersWallet byUserId = walletService.getByUserId(loginLog.getUserId());
                if (byUserId.getBalance().doubleValue() >= data.getAmount().doubleValue()) {
                    double fee = Double.parseDouble(systemservicefee);
                    double persent = Double.parseDouble(systemtaxespersent);
                    BigDecimal amount = data.getAmount();
                    data.setRequestAmount(amount);
                    if (persent > 0) {
                        double v = amount.doubleValue();
                        v = (v * persent) / 100;
                        data.setTaxes(BigDecimal.valueOf(v));
                        amount = amount.subtract(BigDecimal.valueOf(v));
                    } else {
                        data.setTaxes(BigDecimal.valueOf(0));
                    }
                    if (persent > 0) {
                        data.setServiceCharge(BigDecimal.valueOf(fee));
                        amount = amount.subtract(BigDecimal.valueOf(fee));
                    } else {
                        data.setServiceCharge(BigDecimal.valueOf(0));
                    }
                    data.setAmount(amount);
                    System.out.println("AMOUNT:" + amount);
                    // System.out.println(data);
                    boolean b = walletService.myWithdrawal(data);
                    if (b) {
                        List<Users> byAdminList = userService.findByAdminList();
                        UsersAuthentication byUserId1 = usersAuthenticationService.getFindByUserId(data.getUserId());
                        for (Users users : byAdminList) {
                            WithdrawalAppervalMsg orderSuccessMsg = new WithdrawalAppervalMsg();
                            orderSuccessMsg.setOpenId(users.getMpOpenid());
                            orderSuccessMsg.setTime2(DateUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss"));
                            orderSuccessMsg.setAmount3(data.getAmount().doubleValue());
                            orderSuccessMsg.setThing1(byUserId1.getName());
                            wechatMpMessageService.sendWithdrawalAppervalMessage(orderSuccessMsg);
                        }
                        return Result.ok();
                    } else {
                        return Result.failure();
                    }
                } else {
                    return Result.failure();
                }
            } else {
                return Result.failure();
            }
        } else {
            return Result.failure();
        }


    }

    @IsLogin
    @PostMapping("/backwithdrawal")
    @ResponseBody
    public Result backwithdrawal(@RequestBody UsersWalletLog data) throws AuthException {
        System.out.println(data);
        LoginLog loginLog = AuthConstant.getLoginLog();
        data.setOperatorId(loginLog.getUserId());
        if (data.getState() == 2) {

            boolean b = walletService.reNoChange(data);
            if (b) {
                return Result.ok();
            } else {
                return Result.failure();
            }
        } else if (data.getState() == 1) {
            boolean b = walletService.reChange(data);
            if (b) {
                return Result.ok();
            } else {
                return Result.failure();
            }
        } else {
            return Result.failure();
        }

    }


    @IsLogin
    @PostMapping("/myPaymentTransfer")
    @ResponseBody
    public Result myPaymentTransfer(@RequestBody JSONObject object) throws AuthException {

        BigDecimal price = object.getBigDecimal("price");
        String name = object.getString("name");

        long userId = object.getLongValue("userId");
        LoginLog loginLog = AuthConstant.getLoginLog();

        if (price.doubleValue() > 0) {
            UsersWallet wallet = walletService.getByUserId(loginLog.getUserId());
            System.out.println(wallet);
            BigDecimal balance = wallet.getBalance();
            System.out.println("----------------------WALLET------------------------------");
            System.out.println(balance.doubleValue() > price.doubleValue());
            if (balance.compareTo(price) >= 0) {
                UsersWalletTransfer walletTransfer = new UsersWalletTransfer();
                walletTransfer.setUserId(loginLog.getUserId());
                walletTransfer.setOperatorId(loginLog.getUserId());
                walletTransfer.setToUserId(userId);
                walletTransfer.setPrice(price);
                walletTransfer.setType(7);
                walletTransfer.setRemark(name + "پۇل يۆتكىدى");
                boolean b = usersWalletTransferService.myReChange(walletTransfer);
                if (b) {
                    notifyService.sendMessageUserType(7, walletTransfer.getUserId(), walletTransfer.getRemark());
                    return Result.ok();
                } else {
                    return Result.failure();
                }
            } else {
                // throw new AuthException(ResultCode.REQUEST_ERROR_PAYMENT_REQUIRED, "users.wallet.insufficient.balance");
                return Result.failureCode(403, "users.wallet.insufficient.balance");
            }
        } else {
            return Result.failure();
        }

    }

    @IsLogin
    @PostMapping("/backIntegral")
    @ResponseBody
    public Result backIntegral(@RequestBody UsersWalletIntegralLog data) {
        LoginLog loginLog = AuthConstant.getLoginLog();
        data.setOperatorId(loginLog.getUserId());
        boolean b = walletService.reIntegraChange(data);
        if (b) {
            return Result.ok();
        } else {
            return Result.failure();
        }


    }


    //sign
    @IsLogin
    @PostMapping("/sign")
    @ResponseBody
    public Result getSign() {
        LoginLog loginLog = AuthConstant.getLoginLog();
        boolean b = walletService.reIntegraChange(loginLog.getUserId(), 2);
        if (b) {
            UsersSignLog signLog = signLogService.getBySign();
            if (signLog == null) {
                UsersWallet byUserId = walletService.getByUserId(loginLog.getUserId());
                UsersSignLog sign = new UsersSignLog();
                sign.setWalletId(byUserId.getId());
                sign.setUserId(loginLog.getUserId());
                sign.setIntegral(2);
                signLogService.save(sign);
                return Result.ok();
            } else {
                return Result.ok();
            }
        } else {
            return Result.failure();
        }

    }

    @IsLogin
    @GetMapping("/signList")
    @ResponseBody
    public Result getSignList() {
        LoginLog loginLog = AuthConstant.getLoginLog();
        QueryWrapper<UsersSignLog> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(UsersSignLog::getUserId, loginLog.getUserId());
        queryWrapper.select("DATE_FORMAT(CREATE_DATE, '%Y-%m-%d')");
        Function<Object, String> f = (o -> o.toString());
        List<String> maps = signLogService.listObjs(queryWrapper, f);
        Map<String, Object> info = walletService.getInfo();
        long count = signLogService.count(queryWrapper);
        info.put("data", maps);
        info.put("count", count);
        return Result.ok(info);


    }

    //
    @IsLogin
    @PostMapping("/withdrawalStatus")
    public Result withdrawalStatus(
            @RequestParam(name = "id", defaultValue = "0") long id,
            @RequestParam(name = "status", defaultValue = "0") int status,
            @RequestParam(name = "imageId", defaultValue = "0") long imageId) {
        LoginLog loginLog = AuthConstant.getLoginLog();

        if (status > 0 && id > 0 ) {
            UsersWalletWithdrawal withdrawal = walletWithdrawalService.getById(id);
            withdrawal.setId(id);
            withdrawal.setStatus(status);
           if(imageId>0){
                withdrawal.setAuditImage(imageId);
            }
            withdrawal.setOperatorId(loginLog.getUserId());
            withdrawal.setUpdateDate(new Date());
            boolean b = walletWithdrawalService.updateById(withdrawal);
            if (b) {
                if (status == 3) {

                    boolean bb = walletLogService.withdrawalStatus(withdrawal);

                    UsersWalletLog data = new UsersWalletLog();
                    data.setPrice(withdrawal.getRequestAmount());
                    data.setBalanceOld(withdrawal.getBalanceOld());
                    data.setUserId(withdrawal.getUserId());
                    data.setStatus(2);
                    data.setRemark("پۇل چۈشۈرۈش ئىلتىماسى تەستىقلانمىدى");
                    data.setOperatorId(loginLog.getUserId());
                    walletService.reChange(data);
                    notifyService.sendMessageUserType(3, data.getUserId(), data.getRemark());
                }

                return Result.ok();
            } else {
                return Result.failure();
            }
        } else {
            return Result.failure();
        }

    }


    @IsLogin
    @GetMapping("myIncomeExpenses")
    public Result myIncomeExpenses() {


        Map<String, Object> info = walletLogService.myIncomeExpenses();

        return Result.ok(info);


    }

    //  @IsLogin
    @GetMapping("/findByLevelLogList")
    @ResponseBody
    public Result findByLevelLogList(@RequestParam(name = "state", defaultValue = "0") int state) {

        List<Map<String, Object>> info = walletLogService.findByLevelLogList(state);
        return Result.ok(info);

    }


    @GetMapping("/getWithdrawalInfo")
    public Result getWithdrawalInfo(@RequestParam(name = "id", defaultValue = "0") long id) {
        AuthConstant.setPathUrl(uploadhost);
        Map<String, Object> info = walletWithdrawalService.getWithdrawalInfo(id);
        return Result.ok(info);
    }


    @IsLogin
    @PostMapping("/auditWithdrawalInfo")
    @ResponseBody
    public Result auditWithdrawalInfo(@RequestBody JSONObject object) {
        UsersWalletWithdrawal data = object.toJavaObject(UsersWalletWithdrawal.class);
        LoginLog loginLog = AuthConstant.getLoginLog();
        data.setOperatorId(loginLog.getUserId());
        boolean b = walletWithdrawalService.updateById(data);
        if (b) {
            return Result.ok();
        } else {
            return Result.failure();
        }


    }

    @IsLogin
    //getAgentUserFeild
    @GetMapping("/findByPerList")
    public Result findByPerList(@RequestParam(name = "userId", defaultValue = "0") long userId) {
        if(userId==0){
            LoginLog loginLog = AuthConstant.getLoginLog();
            userId = loginLog.getUserId();
        }

        List<Map<String, Object>> list = walletLogService.findByPerList(userId);

        return Result.ok(list);
    }

    @IsLogin
    //getAgentUserFeild
    @GetMapping("/findByPerUsersList")
    public Result findByPerUsersList(@RequestParam(name = "userId", defaultValue = "0") long userId,
                                     @RequestParam(name = "date", defaultValue = "") String date) {
        if(userId==0){
            LoginLog loginLog = AuthConstant.getLoginLog();
            userId = loginLog.getUserId();
        }
        System.out.println("findByPerUsersList:"+userId);
         String replace = date.replace("-", "");
         replace=replace+"::"+AuthConstant.getLanguage();
         String day = DateUtil.format(new Date(), "dd");
        Date sdate = DateUtil.parse(date+"-"+day);
         boolean sameMonth = DateUtil.isSameMonth(new Date(), sdate);
        System.out.println("sameMonth:"+sameMonth);

        List<Map<String, Object>> list = walletLogService.findByPerUsersList(userId,date,sameMonth,replace);

        return Result.ok(list);
    }
    @IsLogin
    //getAgentUserFeild
    @GetMapping("/findByPerUser")
    public Result findByPerUser(@RequestParam(name = "userId", defaultValue = "0") long userId,
                                     @RequestParam(name = "date", defaultValue = "") String date) {
        System.out.println("UUUUUUUUUUUUUUUUUUUUUUUUU:"+userId);
        if(userId==0) {
            LoginLog loginLog = AuthConstant.getLoginLog();
            userId = loginLog.getUserId();
        }
            Date sdate = new Date();
            if (StringUtils.isNotEmpty(date)) {
                sdate = DateUtil.parse(date + "-01");
            } else {
                date = DateUtil.format(sdate, "yyyy-MM");
            }

            String replace = date.replace("-", "");
            replace = replace + "::" + AuthConstant.getLanguage();

            boolean sameMonth = DateUtil.isSameMonth(new Date(), sdate);
            System.out.println("sameMonth:" + sameMonth);

            Map<String, Object> list = walletLogService.findByPerUser(userId, "", sameMonth, replace);

            return Result.ok(list);

    }


}
